home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / samples / stretch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-15  |  9.2 KB  |  383 lines

  1. /*
  2.  * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name of
  8.  * Silicon Graphics may not be used in any advertising or
  9.  * publicity relating to the software without the specific, prior written
  10.  * permission of Silicon Graphics.
  11.  *
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
  13.  * ANY KIND,
  14.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  15.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  16.  *
  17.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
  18.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  21.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22.  * OF THIS SOFTWARE.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <math.h>
  29. #include <GL/glut.h>
  30.  
  31.  
  32. #define STEPCOUNT 40
  33. #define FALSE 0
  34. #define TRUE 1
  35. #define MAX(a, b) (((a) > (b)) ? (a) : (b))
  36. #define MIN(a, b) (((a) < (b)) ? (a) : (b))
  37.  
  38.  
  39. enum {
  40.     OP_NOOP = 0,
  41.     OP_STRETCH,
  42.     OP_DRAWPOINT,
  43.     OP_DRAWIMAGE
  44. };
  45.  
  46.  
  47. typedef struct _cRec {
  48.     float x, y;
  49. } cRec;
  50.  
  51. typedef struct _vertexRec {
  52.     float x, y;
  53.     float dX, dY;
  54.     float tX, tY;
  55. } vertexRec;
  56.  
  57.  
  58. #include "loadppm.c"
  59.  
  60. GLenum doubleBuffer;
  61. int imageSizeX, imageSizeY;
  62. char *fileName = 0;
  63. PPMImage *image;
  64. cRec cList[50];
  65. vertexRec vList[5];
  66. int cCount, cIndex[2], cStep;
  67. GLenum op = OP_NOOP;
  68.  
  69.  
  70. void DrawImage(void)
  71. {
  72.  
  73.     glRasterPos2i(0, 0);
  74.     glDrawPixels(image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE,
  75.                  image->data);
  76.  
  77.     glFlush();
  78.     if (doubleBuffer) {
  79.         glutSwapBuffers();
  80.     }
  81.  
  82.     glRasterPos2i(0, 0);
  83.     glDrawPixels(image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE,
  84.                  image->data);
  85. }
  86.  
  87. void DrawPoint(void)
  88. {
  89.     int i;
  90.  
  91.     glColor3f(1.0, 0.0, 1.0);
  92.     glPointSize(3.0);
  93.     glBegin(GL_POINTS);
  94.         for (i = 0; i < cCount; i++) {
  95.             glVertex2f(cList[i].x, cList[i].y);
  96.         }
  97.     glEnd();
  98.  
  99.     glFlush();
  100.     if (doubleBuffer) {
  101.         glutSwapBuffers();
  102.     }
  103. }
  104.  
  105. void InitVList(void)
  106. {
  107.  
  108.     vList[0].x = 0.0;
  109.     vList[0].y = 0.0;
  110.     vList[0].dX = 0.0;
  111.     vList[0].dY = 0.0;
  112.     vList[0].tX = 0.0;
  113.     vList[0].tY = 0.0;
  114.  
  115.     vList[1].x = (float)imageSizeX;
  116.     vList[1].y = 0.0;
  117.     vList[1].dX = 0.0;
  118.     vList[1].dY = 0.0;
  119.     vList[1].tX = 1.0;
  120.     vList[1].tY = 0.0;
  121.  
  122.     vList[2].x = (float)imageSizeX;
  123.     vList[2].y = (float)imageSizeY;
  124.     vList[2].dX = 0.0;
  125.     vList[2].dY = 0.0;
  126.     vList[2].tX = 1.0;
  127.     vList[2].tY = 1.0;
  128.  
  129.     vList[3].x = 0.0;
  130.     vList[3].y = (float)imageSizeY;
  131.     vList[3].dX = 0.0;
  132.     vList[3].dY = 0.0;
  133.     vList[3].tX = 0.0;
  134.     vList[3].tY = 1.0;
  135.  
  136.     vList[4].x = cList[0].x;
  137.     vList[4].y = cList[0].y;
  138.     vList[4].dX = (cList[1].x - cList[0].x) / STEPCOUNT;
  139.     vList[4].dY = (cList[1].y - cList[0].y) / STEPCOUNT;
  140.     vList[4].tX = cList[0].x / (float)imageSizeX;
  141.     vList[4].tY = cList[0].y / (float)imageSizeY;
  142. }
  143.  
  144. void ScaleImage(int sizeX, int sizeY)
  145. {
  146.     GLubyte *buf;
  147.  
  148.     buf = (GLubyte *)malloc(3*sizeX*sizeY);
  149.     gluScaleImage(GL_RGB, image->sizeX, image->sizeY, GL_UNSIGNED_BYTE,
  150.                   image->data, sizeX, sizeY, GL_UNSIGNED_BYTE, buf);
  151.     free(image->data);
  152.     image->data = buf;
  153.     image->sizeX = sizeX;
  154.     image->sizeY = sizeY;
  155. }
  156.  
  157. void SetPoint(int x, int y)
  158. {
  159.  
  160.     cList[cCount].x = (float)x;
  161.     cList[cCount].y = (float)y;
  162.     cCount++;
  163. }
  164.  
  165. void Stretch(void)
  166. {
  167.  
  168.     glBegin(GL_TRIANGLES);
  169.         glTexCoord2f(vList[0].tX, vList[0].tY);
  170.         glVertex2f(vList[0].x, vList[0].y);
  171.         glTexCoord2f(vList[1].tX, vList[1].tY);
  172.         glVertex2f(vList[1].x, vList[1].y);
  173.         glTexCoord2f(vList[4].tX, vList[4].tY);
  174.         glVertex2f(vList[4].x, vList[4].y);
  175.     glEnd();
  176.  
  177.     glBegin(GL_TRIANGLES);
  178.         glTexCoord2f(vList[1].tX, vList[1].tY);
  179.         glVertex2f(vList[1].x, vList[1].y);
  180.         glTexCoord2f(vList[2].tX, vList[2].tY);
  181.         glVertex2f(vList[2].x, vList[2].y);
  182.         glTexCoord2f(vList[4].tX, vList[4].tY);
  183.         glVertex2f(vList[4].x, vList[4].y);
  184.     glEnd();
  185.  
  186.     glBegin(GL_TRIANGLES);
  187.         glTexCoord2f(vList[2].tX, vList[2].tY);
  188.         glVertex2f(vList[2].x, vList[2].y);
  189.         glTexCoord2f(vList[3].tX, vList[3].tY);
  190.         glVertex2f(vList[3].x, vList[3].y);
  191.         glTexCoord2f(vList[4].tX, vList[4].tY);
  192.         glVertex2f(vList[4].x, vList[4].y);
  193.     glEnd();
  194.  
  195.     glBegin(GL_TRIANGLES);
  196.         glTexCoord2f(vList[3].tX, vList[3].tY);
  197.         glVertex2f(vList[3].x, vList[3].y);
  198.         glTexCoord2f(vList[0].tX, vList[0].tY);
  199.         glVertex2f(vList[0].x, vList[0].y);
  200.         glTexCoord2f(vList[4].tX, vList[4].tY);
  201.         glVertex2f(vList[4].x, vList[4].y);
  202.     glEnd();
  203.  
  204.     glFlush();
  205.     if (doubleBuffer) {
  206.         glutSwapBuffers();
  207.     }
  208.  
  209.     if (++cStep < STEPCOUNT) {
  210.         vList[4].x += vList[4].dX;
  211.         vList[4].y += vList[4].dY;
  212.     } else {
  213.         cIndex[0] = cIndex[1];
  214.         cIndex[1] = cIndex[1] + 1;
  215.         if (cIndex[1] == cCount) {
  216.             cIndex[1] = 0;
  217.         }
  218.         vList[4].dX = (cList[cIndex[1]].x - cList[cIndex[0]].x) / STEPCOUNT;
  219.         vList[4].dY = (cList[cIndex[1]].y - cList[cIndex[0]].y) / STEPCOUNT;
  220.         cStep = 0;
  221.     }
  222. }
  223.  
  224. void Key(unsigned char key, int x, int y)
  225. {
  226.  
  227.     switch (key) {
  228.       case 27:
  229.         free(image->data);
  230.         exit(1);
  231.       case 32:
  232.         if (cCount > 1) {
  233.             InitVList();
  234.             cIndex[0] = 0;
  235.             cIndex[1] = 1;
  236.             cStep = 0;
  237.             glEnable(GL_TEXTURE_2D);
  238.             op = OP_STRETCH;
  239.         }
  240.         break;
  241.       default:
  242.         return;
  243.     }
  244.  
  245.     glutPostRedisplay();
  246. }
  247.  
  248. void Mouse(int button, int state, int mouseX, int mouseY)
  249. {
  250.  
  251.     if (state != GLUT_DOWN)
  252.         return;
  253.  
  254.     if (op == OP_STRETCH) {
  255.         glDisable(GL_TEXTURE_2D);
  256.         cCount = 0;
  257.         op = OP_DRAWIMAGE;
  258.     } else {
  259.         SetPoint(mouseX, imageSizeY-mouseY);
  260.         op = OP_DRAWPOINT;
  261.     }
  262.  
  263.     glutPostRedisplay();
  264. }
  265.  
  266. void Animate(void)
  267. {
  268.  
  269.     switch (op) {
  270.       case OP_STRETCH:
  271.         Stretch();
  272.         break;
  273.       case OP_DRAWPOINT:
  274.         DrawPoint();
  275.         break;
  276.       case OP_DRAWIMAGE:
  277.         DrawImage();
  278.         break;
  279.       default:
  280.         break;
  281.     }
  282. }
  283.  
  284. static GLenum Args(int argc, char **argv)
  285. {
  286.     GLint i;
  287.  
  288.     doubleBuffer = GL_FALSE;
  289.  
  290.     for (i = 1; i < argc; i++) {
  291.         if (strcmp(argv[i], "-sb") == 0) {
  292.             doubleBuffer = GL_FALSE;
  293.         } else if (strcmp(argv[i], "-db") == 0) {
  294.             doubleBuffer = GL_TRUE;
  295.         } else if (strcmp(argv[i], "-f") == 0) {
  296.             if (i+1 >= argc || argv[i+1][0] == '-') {
  297.                 printf("-f (No file name).\n");
  298.                 return GL_FALSE;
  299.             } else {
  300.                 fileName = argv[++i];
  301.             }
  302.         } else {
  303.             printf("%s (Bad option).\n", argv[i]);
  304.             return GL_FALSE;
  305.         }
  306.     }
  307.     return GL_TRUE;
  308. }
  309.  
  310. #ifndef __STORM__
  311. void GLUTCALLBACK glut_post_redisplay_p(void)
  312. #else
  313. void glut_post_redisplay_p(void)
  314. #endif
  315. {
  316.       glutPostRedisplay();
  317. }
  318.  
  319. void main(int argc, char **argv)
  320. {
  321.     GLenum type;
  322.  
  323.     glutInit(&argc, argv);
  324.  
  325.     if (Args(argc, argv) == GL_FALSE) {
  326.         exit(1);
  327.     }
  328.  
  329.     if (fileName == 0) {
  330.         printf("No image file.\n");
  331.         exit(1);
  332.     }
  333.  
  334.     image = LoadPPM(fileName);
  335.  
  336.     /* changed powf and logf to pow and log -Brian */
  337. #ifndef __STORM__
  338.     imageSizeX = (int)pow(2.0, (float)((int)(log(image->sizeX)/log(2.0))));
  339.     imageSizeY = (int)pow(2.0, (float)((int)(log(image->sizeY)/log(2.0))));
  340. #else           /* accuracy problems */
  341.     imageSizeX = (int)(pow(2.0, (float)((int)(log(image->sizeX)/log(2.0))))+0.5);
  342.     imageSizeY = (int)(pow(2.0, (float)((int)(log(image->sizeY)/log(2.0))))+0.5);
  343. #endif
  344.     glutInitWindowPosition(0, 0); glutInitWindowSize( imageSizeX, imageSizeY);
  345.  
  346.     type = GLUT_RGB;
  347.     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
  348.     glutInitDisplayMode(type);
  349.  
  350.     if (glutCreateWindow("Stretch") == GL_FALSE) {
  351.         exit(1);
  352.     }
  353.  
  354.     glViewport(0, 0, imageSizeX, imageSizeY);
  355.     gluOrtho2D(0, imageSizeX, 0, imageSizeY);
  356.     glClearColor(0.0, 0.0, 0.0, 0.0);
  357.  
  358.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  359.     glPixelStorei(GL_PACK_ALIGNMENT, 1);
  360.  
  361.     ScaleImage(imageSizeX, imageSizeY);
  362.  
  363.     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  364.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  365.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  366.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  367.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  368.     glTexImage2D(GL_TEXTURE_2D, 0, 3, image->sizeX, image->sizeY, 0,
  369.                  GL_RGB, GL_UNSIGNED_BYTE, (unsigned char *)image->data);
  370.  
  371.     cCount = 0;
  372.     cIndex[0] = 0;
  373.     cIndex[1] = 0;
  374.     cStep = 0;
  375.     op = OP_DRAWIMAGE;
  376.  
  377.     glutKeyboardFunc(Key);
  378.     glutMouseFunc(Mouse);
  379.     glutDisplayFunc(Animate);
  380.     glutIdleFunc(glut_post_redisplay_p);
  381.     glutMainLoop();
  382. }
  383.